/*
 * AgvAPI.cpp
 *
 *  Created on: 16/11/2013
 *      Author: gonzalo
 */

#include "AgvAPI.h"

RobotAgvAPI::RobotAgvAPI(AdminKeys adminKeys) : comAGV(adminKeys.getAgvKey()), comCanastos(adminKeys.getCanastosKey()) {
	if (adminKeys.compartida()) {
		this->comRobotPiezas1 = new middleware::CommunicationRobot12(adminKeys.getLeftRobot12Key());
		this->comRobotPiezas2 = new middleware::CommunicationRobot12(adminKeys.getRightRobot12Key());
	} else {
		this->comRobotPiezas1 = new middleware::CommunicationRobot11(adminKeys.getRobot11Key());
		this->comRobotPiezas2 =  NULL;
	}
	this->id = (int) adminKeys.getAgvKey();
}

std::vector<TipoPieza> RobotAgvAPI::atenderPedidoPiezas() {
	return this->comAGV.obtenerPedidoDePiezas();
}

int RobotAgvAPI::buscarPosicionReemplazo() {
	std::vector<Canasto> canastos = this->comCanastos.obtenerCanastos();
	int posicionLibre = TODOS_OCUPADOS, posicionOcupadaSinUso = TODOS_OCUPADOS;
	for(int i = 0; i < MAX_CANASTOS; i++) {
		/* Si encuentro uno libre ya está, devuelvo ese */
		if (canastos[i].idPieza == 0) {
			posicionLibre = i;
			break;
		}
		/* Me guardo el primer ocupado sin uso por si no encuentro libres */
		if (canastos[i].uso == 0 && posicionOcupadaSinUso == TODOS_OCUPADOS) {
			posicionOcupadaSinUso = i;
		}
	}
	this->comCanastos.liberarCanastos();
	return ( posicionLibre == TODOS_OCUPADOS ) ? posicionOcupadaSinUso : posicionLibre;
}

void RobotAgvAPI::reemplazarCanasto(TipoPieza pieza, int posicion) {
	PedidoCanasto pedido;
	pedido.idPieza = pieza;
	pedido.idAgv = this->id;
	CLogger::log("Pido canasto de la pieza " + StringUtils::itos(pieza) +" al robot 5.");
	this->comRobot5.pedirCanastoAR5(pedido);
	CLogger::log("Incremento pedidos del robot 5.");
	this->comRobot5.incrementarPedidos(R5_PEDIDOS_PENDIENTES_CANASTOS);
	CLogger::log("Despierto al 5.");
	this->comRobot5.despertarInteligente();
	CLogger::log("Despertoooo al 5.");

	Canasto recibido = this->comRobot5.recibirCanastoDel5(this->id);

	CLogger::log("Recibi el canasto del robot 5");

	this->comCanastos.obtenerCanastos();
	this->comCanastos.reemplazarCanasto(recibido, posicion);
	CLogger::log("Reemplazo canasto "+ StringUtils::itos(pieza) + " en posicion " + StringUtils::itos(posicion));
	if (this->comCanastos.atenderEsperaDePiezaEnCinta1(pieza)) {
		this->comRobotPiezas1->despertarHayPieza();
		if (this->comRobotPiezas2) {
			this->comRobotPiezas2->despertarHayPieza();
		}
	}
	if (this->comCanastos.atenderEsperaDePiezaEnCinta2(pieza) && this->comRobotPiezas2) {
		this->comRobotPiezas1->despertarHayPieza();
		if (this->comRobotPiezas2) {
			this->comRobotPiezas2->despertarHayPieza();
		}
	}
	this->comCanastos.liberarCanastos();
}

EstadoCanasto RobotAgvAPI::getEstadoCanasto(TipoPieza pieza) {
	return this->comCanastos.getEstadoCanasto(pieza);
}

RobotAgvAPI::~RobotAgvAPI() {
	if(this->comRobotPiezas1) delete this->comRobotPiezas1;
	if(this->comRobotPiezas2) delete this->comRobotPiezas2;
}

std::string RobotAgvAPI::mostrarCanastos(std::vector<Canasto> cs) {
	std::stringstream ss;
	ss << "Estado Canastos \n";
	for (int i = 0; i < 10; i++) {
		ss << "Canasto "<<i<<": "<<cs[i].idPieza<<"("<<cs[i].cantidad<<") [Uso "<<cs[i].uso<<"]"<< std::endl;
	}
	ss << std::endl;
	return ss.str();
}
